using B.S.Medical.Api.Read.Application.Command.Payment;
using B.S.Medical.ErrorCode;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using System.Threading.Tasks;
using System;

namespace B.S.Medical.Api.Read.Controllers.Payment
{
    /// <summary>
    /// 支付相关控制器
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class PaymentController : ControllerBase
    {
        private readonly IMediator _mediator;
        private readonly ILogger<PaymentController> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="mediator">中介者</param>
        /// <param name="logger">日志记录器</param>
        public PaymentController(IMediator mediator, ILogger<PaymentController> logger)
        {
            _mediator = mediator;
            _logger = logger;
        }

        /// <summary>
        /// 获取患者余额和充值记录
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <param name="startDate">开始日期（可选，默认为一年前）</param>
        /// <param name="endDate">结束日期（可选，默认为当前日期）</param>
        /// <returns>患者余额和充值记录信息</returns>
        /// <remarks>
        /// 返回患者当前余额和近一年内的充值记录，包括充值金额、充值时间、支付方式等信息
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<PatientBalanceInfoDto>> GetPatientBalance(
            int patientId, 
            [FromQuery] DateTime? startDate = null, 
            [FromQuery] DateTime? endDate = null)
        {
            _logger.LogInformation($"接收到获取患者余额和充值记录请求，患者ID: {patientId}, 开始日期: {startDate}, 结束日期: {endDate}");
            var command = new GetPatientBalanceCommand 
            { 
                PatientId = patientId,
                StartDate = startDate,
                EndDate = endDate
            };
            return await _mediator.Send(command);
        }

        /// <summary>
        /// 获取患者待缴费项目和卡内余额
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <returns>患者待缴费项目和卡内余额信息</returns>
        /// <remarks>
        /// 返回患者的卡内余额和所有未支付的缴费项目，包括项目名称、科室、医生、金额等信息
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<PatientPaymentInfoDto>> GetPatientPaymentItems(int patientId)
        {
            _logger.LogInformation($"接收到获取患者待缴费项目请求，患者ID: {patientId}");
            var command = new GetPatientPaymentItemsCommand { PatientId = patientId };
            return await _mediator.Send(command);
        }

        /// <summary>
        /// 根据缴费ID查询单条缴费数据信息
        /// </summary>
        /// <param name="paymentId">缴费ID</param>
        /// <returns>缴费详情信息</returns>
        /// <remarks>
        /// 返回缴费详情信息，包括费用类型、就诊科室、医生姓名、就诊人、就诊卡号、费用明细、支付方式、卡内余额、总计金额等
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<PaymentDetailDto>> GetPaymentDetail(int paymentId)
        {
            _logger.LogInformation($"接收到获取缴费详情请求，缴费ID: {paymentId}");
            var command = new GetPaymentDetailCommand { PaymentId = paymentId };
            var result = await _mediator.Send(command);
            _logger.LogInformation($"返回缴费详情结果，状态码: {result.Code}, 消息: {result.Msg}, 是否有数据: {result.Data != null}");
            return result;
        }

        /// <summary>
        /// 查询支付成功详情
        /// </summary>
        /// <param name="paymentId">支付记录ID</param>
        /// <param name="orderNo">订单号（可选，如果没有PaymentId可以使用订单号查询）</param>
        /// <returns>支付成功详情信息</returns>
        /// <remarks>
        /// 返回支付成功详情信息，包括费用类型、就诊科室、医生姓名、就诊人、就诊卡号、费用明细、支付方式、卡内余额、订单金额、订单号、订单时间、订单状态等
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<PaymentSuccessDetailDto>> GetPaymentSuccessDetail(int paymentId = 0, string orderNo = null)
        {
            _logger.LogInformation($"接收到获取支付成功详情请求，缴费ID: {paymentId}, 订单号: {orderNo}");
            var command = new GetPaymentSuccessDetailCommand 
            { 
                PaymentId = paymentId,
                OrderNo = orderNo
            };
            return await _mediator.Send(command);
        }

        /// <summary>
        /// 获取退款信息
        /// </summary>
        /// <param name="paymentId">支付记录ID</param>
        /// <param name="orderNo">订单号（可选，如果没有PaymentId可以使用订单号查询）</param>
        /// <param name="patientId">患者ID（可选，如果没有PaymentId和OrderNo可以使用患者ID查询最近的支付记录）</param>
        /// <returns>退款信息</returns>
        /// <remarks>
        /// 返回退款信息，包括患者姓名、身份证号、是否本人、卡内余额、可退款金额等
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<RefundInfoDto>> GetRefundInfo(int paymentId = 0, string orderNo = null, int patientId = 0)
        {
            _logger.LogInformation($"接收到获取退款信息请求，缴费ID: {paymentId}, 订单号: {orderNo}, 患者ID: {patientId}");
            var command = new GetRefundInfoCommand
            {
                PaymentId = paymentId,
                OrderNo = orderNo,
                PatientId = patientId
            };
            return await _mediator.Send(command);
        }

        /// <summary>
        /// 获取患者已缴费项目
        /// </summary>
        /// <param name="patientId">患者ID</param>
        /// <returns>患者已缴费项目信息</returns>
        /// <remarks>
        /// 返回患者的已缴费项目列表，包括项目名称、科室、医生、金额、支付方式、支付状态、支付时间等信息
        /// </remarks>
        [HttpGet]
        public async Task<ApiResult<PatientPaidItemsDto>> GetPaidPaymentItems(int patientId)
        {
            _logger.LogInformation($"接收到获取患者已缴费项目请求，患者ID: {patientId}");
            var command = new GetPaidPaymentItemsCommand 
            { 
                PatientId = patientId
            };
            return await _mediator.Send(command);
        }

        /// <summary>
        /// 提交退款（备用）
        /// </summary>
        /// <param name="request">退款请求</param>
        /// <returns>退款结果</returns>
        /// <remarks>
        /// 提交退款请求，返回退款结果，包括是否成功、退款金额、退款后卡内余额、退款流水号、退款时间等
        /// </remarks>
        [HttpPost]
        public async Task<ApiResult<RefundResultDto>> SubmitRefund(SubmitRefundCommand request)
        {
            _logger.LogInformation($"接收到提交退款请求，订单号: {request?.OrderNo}, 退款金额: {request?.RefundAmount}");
            return await _mediator.Send(request);
        }
    }
}